from transsys import DotParameters
from transsys import TimeSeries
from transsys import TranssysProgramParser
from transsys import TranssysInstance
from django.core.exceptions import ValidationError

import tempfile
from django.shortcuts import render_to_response, redirect
from django.http import HttpResponseRedirect
from django.http import HttpResponse
from django.http import Http404
from django.core.urlresolvers import reverse
from django.utils import simplejson
from django import template
from django.forms import ValidationError
from django.contrib import messages
from ts.validators import *
from pyPdf import PdfFileReader, PdfFileWriter
from transsys import Factor
from transsys import ExpressionNodeValue
from transsys import *
import random

from matplotlib.backends.backend_agg import FigureCanvasAgg as FigureCanvas
from matplotlib.figure import Figure

from ts.utils import write_dot, dot2img
from ts.config import *
# Create your views here.

def home(request):
    #print request.session['ts_programs']
    request.session['ts_program'] = None
    if request.session.get('ts_programs', False):
        ts_programs=request.session['ts_programs']
    else:
        ts_programs=[]
        request.session['ts_programs'] = ts_programs
    request.session.modified=True
    return render_to_response('transsys/index.html',
                              {'ts_programs':ts_programs},
                              context_instance=template.RequestContext(request))

def viewTP(request, tp_name):
    #Check whether working in simgenex work bench or not
    extend_template = "transsys/base_transsys.html"
    try:
        with_sgx = int(request.REQUEST["with_sgx"])
        if with_sgx == 1:
            extend_template = "simgenex/base_simgenex.html"
    except KeyError:
        #Ignore
        pass
    #Find the transsys program with given name
    ts_program = _check_tp_name(request, tp_name)
    #Update current transsys program in session
    request.session['ts_program'] = ts_program
    request.session.modified=True

    if(len(ts_program["tp"].gene_list) != 0):
        return render_to_response('transsys/viewTranssysProgram.html',
                              {'src': reverse('ts.views.getImage', args=[tp_name]),
                               'ts_programs':request.session['ts_programs'],
                               'extend_template':extend_template},
                              context_instance=template.RequestContext(request))
    else:
        return render_to_response('transsys/viewTranssysProgram.html',
                              {'src' : None,
                               'ts_programs':request.session['ts_programs'],
                               'extend_template':extend_template},
                              context_instance=template.RequestContext(request))

def getImage(request, tp_name):
    ts_program = _check_tp_name(request, tp_name)
    if(len(ts_program["tp"].gene_list) != 0):
        tra = str(ts_program["tp"])
        dot_parameters =  DotParameters()
        ts_program["tp"].dot_positions_circle(200, 200, 150)
        #dot_code = tra2dot(ts_program["tp"], dot_parameters)
        dot_code = write_dot(ts_program["tp"])
        #Hardcode return png image
        #TODO: support set preferences image output
        #binary = tra2img(tra, IMAGE_OUTPUT_EXTENSION)
        binary = dot2img(dot_code, IMAGE_OUTPUT_EXTENSION)
        response = HttpResponse(mimetype="image/"+ IMAGE_OUTPUT_EXTENSION)
        response.write(binary)
        return response
        #tra2svg(tra, settings.MEDIA_ROOT + png_src)
    else:
        raise Http404

def getPDF(request, tp_name):

    """NO LONGER USE! Return PDF version of transsys program visualization."""
    #Find the transsys program with given name
    ts_program = _check_tp_name(request, tp_name)
    tra = str(ts_program)
    pdf_src = tempfile.mktemp() + ".pdf"
    tra2pdf(tra, pdf_src)
    
    #create response object
    response = HttpResponse(mimetype='application/pdf')
    response['Content-Disposition'] = 'attachment; filename=' + tp_name + '.pdf'
    
    inPdf = PdfFileReader(file(pdf_src, 'rb'))
    output = PdfFileWriter()
    # get number of pages
    num_pages = inPdf.getNumPages()
    for i in range(num_pages):
        output.addPage(inPdf.getPage(i))
    #stream to browser
    outputStream = response
    output.write(response)
    outputStream.close()
    return response
    
def addTranssysProgram(request):
    """Add new transsys program via WEB interface"""
    #Check whether working in simgenex work bench or not
    extend_template = "transsys/base_transsys.html"
    try:
        with_sgx = int(request.REQUEST["with_sgx"])
        if with_sgx == 1:
            extend_template = "simgenex/base_simgenex.html"
    except KeyError:
        #Ignore
        pass
    if(request.method == "GET"):
        request.session["ts_program"] = None
        request.session.modified = True
        return render_to_response('transsys/addTranssysProgram.html', 
                                  {'ts_programs':request.session['ts_programs']},
                                  context_instance=template.RequestContext(request))
    elif(request.method== "POST"):
        try:
            tp_name = _clean_tp_name(request.session['ts_programs'], request.REQUEST["name"])
            tp_desc = str(request.REQUEST["desc"])
            tp = TranssysProgram(tp_name)
            tp.comments.append(tp_desc)
            ts_program = {"tp":tp}

            #ts_program = {'tp':TranssysProgram(tp_name) , 'desc':ts_desc}
            print ts_program
            if request.session.get('ts_programs', False):
                request.session['ts_programs'].append(ts_program)
            else:
                request.session['ts_programs'] = [ts_program,]
            request.session.modified = True
            return redirect(tp_name+"/view")
        except ValidationError, e:
            messages.error(request, e.messages[0])
            return render_to_response('transsys/addTranssysProgram.html',
                                  {'ts_programs':request.session['ts_programs'],
                                  'extend_template':extend_template},
                                  context_instance=template.RequestContext(request))

def uploadTranssysProgram(request):
    """Add new transsys program from uploading file"""
    if(request.method == "GET"):
        request.session["ts_program"] = None
        request.session.modified = True
        return render_to_response('transsys/uploadTranssysProgram.html',
                                  {'ts_programs':request.session['ts_programs']},
                                  context_instance=template.RequestContext(request))
    elif(request.method== "POST"):
        try:
            tp_file = request.FILES["tp_file"]
            tp_parser = TranssysProgramParser(tp_file)
            tp = tp_parser.parse_transsys()
            ts_program = {"tp":tp}
            #ts_program = {'tp':TranssysProgram(tp_name) , 'desc':ts_desc}
            print ts_program
            if request.session.get('ts_programs', False):
                request.session['ts_programs'].append(ts_program)
            else:
                request.session['ts_programs'] = [ts_program,]
            request.session.modified = True
            return redirect(tp.name +"/view")
        except ValidationError, e:
            messages.error(request, e.messages[0])
            return render_to_response('transsys/addTranssysProgram.html',
                                  {'ts_programs':request.session['ts_programs']},
                                  context_instance=template.RequestContext(request))


def delTP(request, tp_name):
    """Delete the transsys program which has given name"""
    ts_program = _check_tp_name(request, tp_name)
    print "ts_program: ", ts_program
    ts_programs = request.session['ts_programs']
    print "ts_programs: ", ts_programs
    cur_ts_program = request.session['ts_program']
    
    print "cur_ts_program: ", cur_ts_program
    if ts_program != cur_ts_program:
        ts_programs.remove(ts_program)
        msg="transsys program is removed successfully!"
        result = {"status":"success","msg":msg}
    else:
        msg="Unable to remove transsys program due to it is currently activated!"
        result = {"status":"failed","msg":msg}
    request.session.modified=True
    return HttpResponse(simplejson.dumps(result), mimetype='application/javascript')

def addFactor(request, tp_name):
    """Add new factor to current activated transsys program"""
    #Check whether working in simgenex work bench or not
    extend_template = "transsys/base_transsys.html"
    try:
        with_sgx = int(request.REQUEST["with_sgx"])
        if with_sgx == 1:
            extend_template = "simgenex/base_simgenex.html"
    except KeyError:
        #Ignore
        with_sgx = 0
    #Find the transsys program with given name
    ts_program = _check_tp_name(request, tp_name)
    #Use traditional HTML form
    if(request.method == "GET"):
        return render_to_response('transsys/addFactor.html',
                                  {'ts_programs':request.session['ts_programs'],
                                   'extend_template':extend_template},
                                  context_instance=template.RequestContext(request))
    elif (request.method == "POST"):
        try:
            fname = _clean_factor_name(ts_program["tp"], request.REQUEST["name"])
            fdecay = _clean_expression_value(request.REQUEST["decay"])
            fdiffusibility = _clean_expression_value(request.REQUEST["diffusibility"])

            decay = ExpressionNodeValue(fdecay)
            diffusibility = ExpressionNodeValue(fdiffusibility)
            factor = Factor(fname, decay, diffusibility)
            ts_program["tp"].factor_list.append(factor)
            request.session.modified=True
            return redirect(reverse('ts.views.viewTP', args=[tp_name])+"?with_sgx="+str(with_sgx))
        except ValidationError, e:
            messages.error(request, e.messages[0])
            return render_to_response('transsys/addFactor.html',
                                  {'ts_programs':request.session['ts_programs'],
                                   'extend_template':extend_template},
                                  context_instance=template.RequestContext(request))
    
    
def editFactor(request, tp_name, f_name):
    """Edit existed factor"""
    extend_template = "transsys/base_transsys.html"
    try:
        with_sgx = int(request.REQUEST["with_sgx"])
        if with_sgx == 1:
            extend_template = "simgenex/base_simgenex.html"
    except KeyError:
        #Ignore
        with_sgx = 0
    #Find the transsys program with given name
    ts_program = _check_tp_name(request, tp_name)
    #Find factor
    try:
        factor = ts_program["tp"].find_factor(str(f_name))
    except StandardError:
        msg = "Factor "+f_name+" does not exist"
        print msg
        raise Http404
    
    #Use traditional HTML form
    if(request.method == "GET"):
        return render_to_response('transsys/editFactor.html',
                                  {'ts_programs':request.session['ts_programs'],
                                   'factor':factor,
                                   'extend_template':extend_template},
                                  context_instance=template.RequestContext(request))
    elif (request.method == "POST"):
        if 'submit' in request.POST:
            try:
                fname = str(request.REQUEST["name"])
                if fname != factor.name:
                    fname = _clean_factor_name(ts_program, fname)
                fdecay = _clean_expression_value(request.REQUEST["decay"])
                fdiffusibility = _clean_expression_value(request.REQUEST["diffusibility"])
                decay = ExpressionNodeValue(fdecay)
                diffusibility = ExpressionNodeValue(fdiffusibility)
                factor.name = fname
                factor.decay_expression = decay
                factor.diffusibility_expression = diffusibility
                request.session.modified=True
                return redirect(reverse('ts.views.viewTP', args=[tp_name])+"?with_sgx="+str(with_sgx))
            except ValidationError, e:
                messages.error(request, e.messages[0])
                return render_to_response('transsys/addFactor.html',
                                      {'ts_programs':request.session['ts_programs'],
                                       'factor':factor,
                                       'extend_template':extend_template},
                                      context_instance=template.RequestContext(request))
        elif 'delete' in request.POST:
            if _can_delete(ts_program["tp"], factor):
                    ts_program["tp"].factor_list.remove(factor)
            else:
                msg = "Unable to delete factor " + factor.name + ". It may be regulated by a gene, or encoded a gene"
                messages.error(request, msg)
            request.session.modified=True
            return redirect(reverse('ts.views.viewTP', args=[tp_name])+"?with_sgx="+str(with_sgx))
    
def delFactor(request, tp_name, f_name):
    """Delete factor in the given transsys program"""
    extend_template = "transsys/base_transsys.html"
    try:
        with_sgx = int(request.REQUEST["with_sgx"])
        if with_sgx == 1:
            extend_template = "simgenex/base_simgenex.html"
    except KeyError:
        #Ignore
        with_sgx == 0
    #Find the transsys program with given name
    ts_program = _check_tp_name(request, tp_name)
    #Find factor
    try:
        factor = ts_program["tp"].find_factor(str(f_name))
    except StandardError:
        msg = "Factor "+f_name+" does not exist"
        print msg
        raise Http404

    if request.is_ajax():
        result = {}
        if _can_delete(ts_program["tp"], factor):
            ts_program["tp"].factor_list.remove(factor)
            msg = "The factor is removed successfully!"
            result = {"status":"success","msg":msg}
        else:
            msg = "Unable to delete factor " + factor.name + ". It may be regulated by a gene, or encoded a gene"
            #messages.error(request, msg)
            result = {"status":"failed","msg":msg}
        request.session.modified=True
        return HttpResponse(simplejson.dumps(result), mimetype='application/javascript')
    else:
        if _can_delete(ts_program["tp"], factor):
            ts_program["tp"].factor_list.remove(factor)
        else:
            msg = "Unable to delete factor " + factor.name + ". It may be regulated by a gene, or encoded a gene"
            messages.error(request, msg)
        request.session.modified=True
        return redirect(reverse('ts.views.viewTP', args=[tp_name])+"?with_sgx="+str(with_sgx))

def addGene(request, tp_name):
    """Add new gene to current activated transsys program"""
    #Check whether working in simgenex work bench or not
    extend_template = "transsys/base_transsys.html"
    try:
        with_sgx = int(request.REQUEST["with_sgx"])
        if with_sgx == 1:
            extend_template = "simgenex/base_simgenex.html"
    except KeyError:
        #Ignore
        with_sgx = 0
    #Find the transsys program with given name
    ts_program = _check_tp_name(request, tp_name)
    
    if(request.method == "GET"):
        return render_to_response('transsys/addGene.html', 
                                  {'ts_program':ts_program,
                                   'ts_programs':request.session['ts_programs'],
                                   'extend_template':extend_template},
                                  context_instance=template.RequestContext(request))
    elif(request.method== "POST"):
        try:
            g_name = _clean_gene_name(ts_program["tp"], request.REQUEST["name"])
            g_product = str(request.REQUEST["product"])
            p_type_list = request.REQUEST.getlist("ptype")
            p_expr_list = request.REQUEST.getlist("pexpr")
            p_factor_list = request.REQUEST.getlist("pfactor")
            p_expr1_list = request.REQUEST.getlist("pexpr1")
            p_expr2_list = request.REQUEST.getlist("pexpr2")
            
            product = ts_program["tp"].find_factor(str(g_product))
            gene = Gene(g_name, product)
            
            for i in range(len(p_type_list)):
                p_type = p_type_list[i]
                if(p_expr_list[i]!="undefined"):
                    p_expr = _clean_expression_value(p_expr_list[i])
                p_factor = p_factor_list[i]
                if(p_expr1_list[i]!="undefined"):
                    p_expr1 = _clean_expression_value(p_expr1_list[i])
                if(p_expr2_list[i]!="undefined"):
                    p_expr2 = _clean_expression_value(p_expr2_list[i])
                
                if (p_type == "constitutive"):
                    expression_node = ExpressionNodeValue(p_expr)
                    promoter = PromoterElementConstitutive(expression_node)
                    gene.promoter.append(promoter)
                elif (p_type == "activate"):
                    expression_node1 = ExpressionNodeValue(p_expr1)
                    expression_node2 = ExpressionNodeValue(p_expr2)
                    factor = ts_program["tp"].find_factor(str(p_factor))
                    promoter = PromoterElementActivate(expression_node1, expression_node2,[factor])
                    gene.promoter.append(promoter)
                elif (p_type == "repress"):
                    expression_node1 = ExpressionNodeValue(p_expr1)
                    expression_node2 = ExpressionNodeValue(p_expr2)
                    factor = ts_program["tp"].find_factor(str(p_factor))
                    promoter = PromoterElementRepress(expression_node1, expression_node2,[factor])
                    gene.promoter.append(promoter)
                else:
                    print "Error"
                    
            ts_program["tp"].gene_list.append(gene)
            request.session.modified = True
            return redirect(reverse('ts.views.viewTP', args=[tp_name])+"?with_sgx="+str(with_sgx))
            
        except ValidationError, e:
            messages.error(request, e.messages[0])
            return render_to_response('transsys/addGene.html',
                                      {'ts_programs':request.session['ts_programs'],
                                      'extend_template':extend_template},
                                      context_instance=template.RequestContext(request))
def editGene(request, tp_name, g_name):
    """Edit given name gene"""
    extend_template = "transsys/base_transsys.html"
    try:
        with_sgx = int(request.REQUEST["with_sgx"])
        if with_sgx == 1:
            extend_template = "simgenex/base_simgenex.html"
    except KeyError:
        #Ignore
        with_sgx =0
    #Find the transsys program with given name
    ts_program = _check_tp_name(request, tp_name)
    
    #Find gene
    try:
        gene = ts_program["tp"].find_gene(str(g_name))
    except StandardError:
        msg = "Factor "+f_name+" does not exist!"
        print msg
        raise Http404
    
    if(request.method == "GET"):
        promoter_list=[]
        for promoter in gene.promoter:
            pos = gene.promoter.index(promoter) + 1
            if(pos%2 == 1):
                css = "odd"
            else:
                css = "even"
            if isinstance(promoter, PromoterElementConstitutive):
                p_type = "constitutive"
                p_expr = promoter.expression
                promoter_list.append({'id':'pro' + str(pos),
                                      'del_id': 'del_pro' + str(pos),
                                      'css':css,
                                      'type':'constitutive', 
                                      'expr':p_expr})
            elif isinstance(promoter, PromoterElementActivate):
                p_type = "activate"
                #TODO: A better solution for more than 1 factor in factor list
                p_factor_list = promoter.factor_list
                p_expr1 = promoter.expression1
                p_expr2 = promoter.expression2
                promoter_list.append({'id':'pro' + str(pos),
                                      'del_id': 'del_pro' + str(pos),
                                      'css':css,
                                      'type':'activate', 
                                      'factor_list':p_factor_list,
                                      'expr1':p_expr1, 
                                      'expr2':p_expr2})
            elif isinstance(promoter, PromoterElementRepress):
                p_type = "repress"
                p_factor_list = promoter.factor_list
                print p_factor_list
                #import pdb;
                #pdb.set_trace();
                p_expr1 = promoter.expression1
                p_expr2 = promoter.expression2
                promoter_list.append({'id':'pro' + str(pos),
                                      'del_id': 'del_pro' + str(pos),
                                      'css':css,
                                      'type':'repress', 
                                      'factor_list':p_factor_list,
                                      'expr1':p_expr1, 
                                      'expr2':p_expr2})
            
        return render_to_response('transsys/editGene.html', 
                                  {'ts_program':ts_program,
                                   'gene': gene, 
                                   'promoter_list':promoter_list,
                                   'ts_programs':request.session['ts_programs'],
                                   'extend_template':extend_template},
                                  context_instance=template.RequestContext(request))
    elif request.method == "POST":
        if "submit" in request.POST:
            try:
                g_name = str(request.REQUEST["name"])
                if g_name != gene.name:
                    g_name = _clean_gene_name(g_name)
                    
                g_product = str(request.REQUEST["product"])
                p_type_list = request.REQUEST.getlist("ptype")
                p_expr_list = request.REQUEST.getlist("pexpr")
                p_factor_list = request.REQUEST.getlist("pfactor")
                p_expr1_list = request.REQUEST.getlist("pexpr1")
                p_expr2_list = request.REQUEST.getlist("pexpr2")
                
                gene.name = g_name
                gene.product = ts_program["tp"].find_factor(str(g_product))
                gene.promoter = []
                
                for i in range(len(p_type_list)):
                    p_type = p_type_list[i]
                    if(p_expr_list[i]!="undefined"):
                        p_expr = _clean_expression_value(p_expr_list[i])
                    p_factor = p_factor_list[i]
                    if(p_expr1_list[i]!="undefined"):
                        p_expr1 = _clean_expression_value(p_expr1_list[i])
                    if(p_expr2_list[i]!="undefined"):
                        p_expr2 = _clean_expression_value(p_expr2_list[i])

                    if (p_type == "constitutive"):
                        expression_node = ExpressionNodeValue(p_expr)
                        promoter = PromoterElementConstitutive(expression_node)
                        gene.promoter.append(promoter)
                    elif (p_type == "activate"):
                        expression_node1 = ExpressionNodeValue(p_expr1)
                        expression_node2 = ExpressionNodeValue(p_expr2)
                        factor = ts_program["tp"].find_factor(str(p_factor))
                        promoter = PromoterElementActivate(expression_node1, expression_node2,[factor])
                        gene.promoter.append(promoter)
                    elif (p_type == "repress"):
                        expression_node1 = ExpressionNodeValue(p_expr1)
                        expression_node2 = ExpressionNodeValue(p_expr2)
                        factor = ts_program["tp"].find_factor(str(p_factor))
                        promoter = PromoterElementRepress(expression_node1, expression_node2,[factor])
                        gene.promoter.append(promoter)
                    else:
                        print "Error"
                request.session.modified = True
                return redirect(reverse('ts.views.viewTP', args=[tp_name])+"?with_sgx="+str(with_sgx))
            except ValidationError, e:
                messages.error(request, e.messages[0])
                return HttpResponseRedirect(reverse("ts.views.editGene", args=(tp_name, g_name))+"?with_sgx="+str(with_sgx))
        elif "delete" in request.POST:
            ts_program["tp"].gene_list.remove(gene)
            request.session.modified=True
            return redirect(reverse('ts.views.viewTP', args=[tp_name])+"?with_sgx="+str(with_sgx))

def delGene(request, tp_name, g_name):
    #Check whether working in simgenex work bench or not
    extend_template = "transsys/base_transsys.html"
    try:
        with_sgx = int(request.REQUEST["with_sgx"])
        if with_sgx == 1:
            extend_template = "simgenex/base_simgenex.html"
    except KeyError:
        #Ignore
        with_sgx =0
    #Find the transsys program with given name
    ts_program = _check_tp_name(request, tp_name)
    #Find gene
    try:
        gene = ts_program["tp"].find_gene(str(g_name))
    except StandardError:
        msg = "Factor "+f_name+" does not exist!"
        print msg
        raise Http404
    if request.is_ajax():
        ts_program["tp"].gene_list.remove(gene)
        request.session.modified=True
        msg = "The gene is deleted successfully!"
        result = {"status":"success","msg":msg}
        
        return HttpResponse(simplejson.dumps(result), mimetype='application/javascript')
    else:
        ts_program["tp"].gene_list.remove(gene)
        request.session.modified=True
        return redirect(reverse('ts.views.viewTP', args=[tp_name])+"?with_sgx="+str(with_sgx))
    
def toTranssys(request, tp_name):
    ts_program = _check_tp_name(request, tp_name)
    return render_to_response('transsys/viewTranssysCode.html',
                       {'transsys_code':str(ts_program["tp"]),
                        'ts_programs':request.session['ts_programs']},
                       context_instance=template.RequestContext(request))

def codeTranssys(request, tp_name):
    extend_template = "transsys/base_transsys.html"
    try:
        with_sgx = int(request.REQUEST["with_sgx"])
        if with_sgx == 1:
            extend_template = "simgenex/base_simgenex.html"
    except KeyError:
        #Ignore
        with_sgx =0
    ts_program = _check_tp_name(request, tp_name)
    if request.method=="GET":
        return render_to_response('transsys/codeTranssys.html',
                       {'transsys_code':str(ts_program["tp"]),
                        'ts_programs':request.session['ts_programs'],
                        'extend_template':extend_template},
                       context_instance=template.RequestContext(request))
    elif request.method=="POST":
        ts_code = str(request.REQUEST["transsys_code"])
        #TODO: Validate and update transsys program
        import StringIO
        tmp = StringIO.StringIO(ts_code)
        parser = TranssysProgramParser(tmp)
        try:
            ts_program["tp"] = parser.parse_transsys()
            request.session.modified=True
            return redirect(reverse('ts.views.viewTP', args=[tp_name])+"?with_sgx="+str(with_sgx))
        except StandardError, e:
            msg="Unable to compile transsys code"
            messages.error(request, msg)
            return render_to_response('transsys/codeTranssys.html',
                       {'transsys_code':ts_code,
                        'ts_programs':request.session['ts_programs'],
                        'extend_template':extend_template},
                       context_instance=template.RequestContext(request))
        
def createTranssysInstance(request, tp_name):
    ts_program = _check_tp_name(request, tp_name)
    #print ts_program
    
    ts_instance = TranssysInstance(ts_program["tp"])
    
    #ts_program["data_set"] = {}
    #request.session.modified = True

    if "data_set" in ts_program:
        new_ds_name = generateUniqueName(ts_program["data_set"].keys())
        print "asad", new_ds_name
    else:
        new_ds_name = "dataset1"
    if request.method == "GET":
        
        request.session.modified = True
        return render_to_response('transsys/createTranssysInstance.html',
                           {'ts_instance':ts_instance,
                            'new_ds_name':new_ds_name,
                            'ts_programs':request.session['ts_programs']},
                           context_instance=template.RequestContext(request))
    elif request.method == "POST":
        
        timestep = int(request.REQUEST['timestep'])
        try:
            store_fc_set = request.REQUEST['store_data']
        except KeyError:
            store_fc_set = None

        if(store_fc_set!=None):
            data_set_name = request.REQUEST['data_set_name']
            dt = {}
            
            for f in ts_program["tp"].factor_list:
                initial_fc = _clean_expression_value(float(request.REQUEST[f.name]))
                dt[f.name] = initial_fc
            if "data_set" in ts_program:
                ts_program["data_set"][data_set_name]=dt
            else:
                ts_program["data_set"] = {data_set_name:dt,}
                
        else:
            #Just do nothing for now
            print store_fc_set
            
        for f in ts_program["tp"].factor_list:
            initial_fc = _clean_expression_value(float(request.REQUEST[f.name]))
            ts_instance.set_factor_concentration(f.name, initial_fc)

        fc_list=[]
        
       

        ti_list = ts_instance.time_series(int(timestep))
        t_series = TimeSeries(ts_instance, timestep)
        for i in (range(int(timestep))):
            f_concentration = []
            for factor in ts_program["tp"].factor_list:
                f_concentration.append(t_series.get_factor_expression_list(factor.name)[i])
            fc_list.append(f_concentration)

        input={"timestep":timestep}
        ts_program["simulation_data"] = t_series
        request.session.modified = True

        return render_to_response('transsys/createTranssysInstance.html',
                                  {'input':input,
                                   'fc_list':fc_list,
                                   'new_ds_name':new_ds_name,
                                   'ts_programs':request.session['ts_programs']},
                                  context_instance=template.RequestContext(request))

def downloadSimulationData(request, tp_name):
    """Return file which should be suitable for reading by the R function read.table(file, header = TRUE)."""
    ts_program = _check_tp_name(request, tp_name)
    data = ts_program["simulation_data"]

    #create response object
    response = HttpResponse(mimetype='text/plain')
    response['Content-Disposition'] = 'attachment; filename=' + tp_name + '.dat'
    data.write_table(response)
    return response
def getDataset(request, tp_name, dt_name):
    """Return data set"""
    ts_program = _check_tp_name(request, tp_name)
    
    if request.is_ajax():
        if dt_name in ts_program["data_set"].keys():
            msg = ""
            data = ts_program["data_set"][dt_name]
            result = {"status":"success","msg":msg, "data":data}

        return HttpResponse(simplejson.dumps(result), mimetype='application/javascript')

def identifyAttractors(request, tp_name):
    """1. Identify attractors by simulating the biological processes with random intitial stage and time steps."""
    ts_program = _check_tp_name(request, tp_name)
    
    if request.method == "GET":
        return render_to_response('transsys/identifyAttractors.html',
                           {'ts_programs':request.session['ts_programs']},
                           context_instance=template.RequestContext(request))
    elif request.method == "POST":
        timestep = int(request.REQUEST['timestep'])
        no_simulations = int(request.REQUEST['no_simulations'])
        c_min = int(request.REQUEST['c_min'])
        c_max = int(request.REQUEST['c_max'])

        input = {"timestep":timestep, "no_simulations":no_simulations, "c_min":c_min, "c_max":c_max}
        f = open("/tmp/rcode.dat", "w")
        f.write("no_simulations")
        for factor in ts_program["tp"].factor_list:
            #write table header
            f.write(' %s' % factor.name)
        f.write("\n")
        # List of list factor concentration for all test
        fc_list =[]
        simulations_list = []
        for i in range(no_simulations):
            #fc list of factor concentration of each factor at the end of one test
            fc = []
            fc_profile = {}
            ti = TranssysInstance(ts_program["tp"])
            #Set randomly initial stage
            for factor in ts_program["tp"].factor_list:
                concentration = random.uniform(c_min, c_max)
                ti.set_factor_concentration(factor.name, concentration)

            t_series = TimeSeries(ti, timestep)
            for factor in ts_program["tp"].factor_list:
                fc.append(t_series.get_factor_expression_list(factor.name)[timestep-1])
                fc_profile[factor.name] = []
                for i in range(timestep):
                    fc_profile[factor.name].append(t_series.get_factor_expression_list(factor.name)[i])
            fc_list.append(fc)
            simulations_list.append(fc_profile)
            t_series.transsys_instance_list()[timestep-1].write_table_line(f)
        f.close()

        #canvas = plot(ts_program["tp"], fc_list)
        #print canvas
        ts_program["fc_list"] = fc_list
        ts_program["simulations_list"] = simulations_list
        #TODO: Add factor_list for users to choose which factor they want to monitor
        request.session.modified = True

        return render_to_response('transsys/identifyAttractors.html',
                                  {'input':input,
                                   'fc_list':fc_list,
                                   'ts_programs':request.session['ts_programs']},
                                  context_instance=template.RequestContext(request))

def plotTimeSeries(request, tp_name, f_name, thumbnail):
    ts_program = _check_tp_name(request, tp_name)
    tp=ts_program["tp"]
    #simulations_list = ts_program["simulations_list"]
    t_series = ts_program["simulation_data"]
    #Find factor
    try:
        factor = ts_program["tp"].find_factor(str(f_name))
    except StandardError:
        msg = "Factor "+f_name+" does not exist"
        print msg
        raise Http404
    #Check weather create thumbnail or full size image
    table_size = 500.0
    thumbnail_size = table_size/float(len(tp.factor_list))
    if thumbnail=="thumbnail":
        fig=Figure(figsize=[2,2], dpi=thumbnail_size/2)
    elif thumbnail=="full":
        fig=Figure()
    else:
        raise Http404
    graph=fig.add_subplot(111)
    x=[]
    y=t_series.get_factor_expression_list(f_name)
    for i in range(len(t_series.get_factor_expression_list(f_name))):
        x.append(i)
    graph.set_xlabel("Factor "+f_name)
    graph.set_ylabel("Expression level")
    graph.plot(x,y, "o-")

    #graph.axis([0,len(x_map.keys())+1, 0,12])
    canvas=FigureCanvas(fig)
    
    response=HttpResponse(content_type='image/png')
    canvas.print_png(response)
    return response

def plotAttractors(request, tp_name, f_name1, f_name2, thumbnail):
    ts_program = _check_tp_name(request, tp_name)
    tp=ts_program["tp"]
    simulations_list = ts_program["simulations_list"]
    #Find factor
    try:
        factor1 = ts_program["tp"].find_factor(str(f_name1))
        factor2 = ts_program["tp"].find_factor(str(f_name2))
    except StandardError:
        msg = "Factor "+f_name+" does not exist"
        print msg
        raise Http404
    #Check weather create thumbnail or full size image
    table_size = 500.0
    thumbnail_size = table_size/float(len(tp.factor_list))
    if thumbnail=="thumbnail":
        fig=Figure(figsize=[2,2], dpi=thumbnail_size/2)
    elif thumbnail=="full":
        fig=Figure()
    else:
        raise Http404
    graph=fig.add_subplot(111)

    graph.set_xlabel(factor2.name)
    graph.set_ylabel(factor1.name)
    color_code = ["b", "g","r", "c", "m", "y", "k"]
    i=0
    for s in simulations_list[:8]:
        x=s[factor2.name]
        y=s[factor1.name]
        graph.plot(x, y, color_code[i%7]+"o-", mew="0.5")
        p1, = graph.plot(x[0], y[0], color_code[i%7]+"s", mew="5", mec=color_code[i%7])
        p2, = graph.plot(x[-1], y[-1], color_code[i%7]+"*", mew="5", mec=color_code[i%7])
        i=i+1
        #for k,v in s.items():
        #    graph.plot(x, v, color_code[i]+"o-", label=k)
        #    
            #graph.scatter(x, s["f2"], c="r")
    if (thumbnail=="full"):
        fig.legend([p1, p2], ["start point", "end point"], "right")
    #graph.scatter(x,y2)
    #graph.set_xticks(x)
    #graph.set_xticklabels([key for(key, value) in x_map.items()])
    #graph.axis([0,len(x_map.keys())+1, 0,12])
    canvas=FigureCanvas(fig)

    response=HttpResponse(content_type='image/png')
    canvas.print_png(response)
    return response
################################################
##methods for internal usage####################
################################################

def _clean_tp_name(ts_programs, tp_name):
    """Verify that given tp_name is not existed in the transsys program list"""
    #TODO: Name must be identifier (No space)
    name = str(tp_name)
    validators=[RequiredValidator(), UniqueTranssysProgramValidator(ts_programs)]
    run_validators(name, validators)
    return name

def _clean_factor_name(ts_program, fname):
    name = str(fname)
    validators=[RequiredValidator(), UniqueFactorValidator(ts_program)]
    run_validators(name, validators)
    return name

def _clean_gene_name(ts_program, gname):
    name = str(gname)
    validators=[RequiredValidator(), UniqueGeneValidator(ts_program)]
    run_validators(name, validators)
    return name

def _clean_expression_value(expression):
    validators=[RequiredValidator(), ExpressionValueValidator()]
    run_validators(expression, validators)
    return float(expression)


def _check_tp_name(request, tp_name):
    #Convert name from url to basic string
    tp_name = tp_name.replace("-", " ")
    #Find the transsys program with given name
    found = False
    
    for tsp in request.session['ts_programs']:
        if tsp["tp"].name == tp_name:
            ts_program = tsp
            found = True
    if(not found):
        msg = "Transsys program "+tp_name+" does not exist!"
        print msg
        raise Http404
    return ts_program

def _can_delete(ts_program, factor):
    #Return True if this factor is not encoded by any gene and it does not regulate any gene as well
    regulated_genes = ts_program.regulated_genes(factor)
    encoding_gene_list = ts_program.encoding_gene_list(factor.name)
    if (regulated_genes == [] and encoding_gene_list == []):
        return True
    else:
        return False

def generateUniqueName(name_list, base="dataset"):
    i = len(name_list) + 1
    new_name = base + str(i)
    while(new_name in name_list):
        i = i+1;
        new_name = base+str(i);
    return new_name